Skip to content

[JTS] Use common branch weight downscaling #153738

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

mtrofin
Copy link
Member

@mtrofin mtrofin commented Aug 15, 2025

This also fixes a bug introduced accidentally in #153651, whereby the JumpTableToSwitch​ would convert all the branch weights to 0 except for one. It didn't trip the test because update_test_checks​ wasn't run with -check-globals​. It is now. This also made noticeable that the direct calls promoted from the indirect call inherited the VP​metadata, which should be dropped as it makes no more sense now.

Copy link
Member Author

mtrofin commented Aug 15, 2025

@llvmbot
Copy link
Member

llvmbot commented Aug 15, 2025

@llvm/pr-subscribers-llvm-transforms

Author: Mircea Trofin (mtrofin)

Changes

This also fixes a bug introduced accidentally in #153651, whereby the JumpTableToSwitch​ would convert all the branch weights to 0 except for one. It didn't trip the test because update_test_checks​ wasn't run with -check-globals​. It is now. This also made noticeable that the direct calls promoted from the indirect call inherited the VP​metadata, which should be dropped as it makes no more sense now.


Full diff: https://github.com/llvm/llvm-project/pull/153738.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp (+6-8)
  • (modified) llvm/test/Transforms/JumpTableToSwitch/basic.ll (+72-9)
diff --git a/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp b/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp
index 9dde131185cf8..9d915d0d967e5 100644
--- a/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp
@@ -159,6 +159,10 @@ expandToSwitch(CallBase *CB, const JumpTableTy &JT, DomTreeUpdater &DTU,
     DTUpdates.push_back({DominatorTree::Insert, B, Tail});
 
     CallBase *Call = cast<CallBase>(CB->clone());
+    // The MD_prof metadata (VP kind), if it existed, can be dropped, it doesn't
+    // make sense on a direct call. Note that the values are used for the branch
+    // weights of the switch.
+    Call->setMetadata(LLVMContext::MD_prof, nullptr);
     Call->setCalledFunction(Func);
     Call->insertInto(B, B->end());
     Switch->addCase(
@@ -180,14 +184,8 @@ expandToSwitch(CallBase *CB, const JumpTableTy &JT, DomTreeUpdater &DTU,
   if (HadProfile && !ProfcheckDisableMetadataFixes) {
     // At least one of the targets must've been taken.
     assert(llvm::any_of(BranchWeights, [](uint64_t V) { return V != 0; }));
-    // FIXME: this duplicates logic in instrumentation. Note: since there's at
-    // least a nonzero and these are unsigned values, it follows MaxBW != 0.
-    uint64_t MaxBW = *llvm::max_element(BranchWeights);
-    SmallVector<uint32_t> ScaledBranchWeights(
-        llvm::map_range(BranchWeights, [MaxBW](uint64_t V) {
-          return static_cast<uint32_t>(V / MaxBW);
-        }));
-    setBranchWeights(*Switch, ScaledBranchWeights, /*IsExpected=*/false);
+    setBranchWeights(*Switch, downscaleWeights(BranchWeights),
+                     /*IsExpected=*/false);
   } else
     setExplicitlyUnknownBranchWeights(*Switch);
   if (PHI)
diff --git a/llvm/test/Transforms/JumpTableToSwitch/basic.ll b/llvm/test/Transforms/JumpTableToSwitch/basic.ll
index 577c2adaf5afa..e3c032b9d4bf7 100644
--- a/llvm/test/Transforms/JumpTableToSwitch/basic.ll
+++ b/llvm/test/Transforms/JumpTableToSwitch/basic.ll
@@ -1,14 +1,39 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 4
 ; RUN: opt < %s -passes=jump-table-to-switch -verify-dom-info -S | FileCheck %s
 ; RUN: opt < %s -passes=jump-table-to-switch -jump-table-to-switch-size-threshold=0 -verify-dom-info -S | FileCheck %s --check-prefix=THRESHOLD-0
 
 @func_array = constant [2 x ptr] [ptr @func0, ptr @func1]
 
+;.
+; CHECK: @func_array = constant [2 x ptr] [ptr @func0, ptr @func1]
+; CHECK: @void_func_array = constant [2 x ptr] [ptr @void_func0, ptr @void_func1]
+; CHECK: @func_array_addrspace_42 = addrspace(42) constant [2 x ptr addrspace(42)] [ptr addrspace(42) @func0_addrspace_42, ptr addrspace(42) @func1_addrspace_42]
+;.
+; THRESHOLD-0: @func_array = constant [2 x ptr] [ptr @func0, ptr @func1]
+; THRESHOLD-0: @void_func_array = constant [2 x ptr] [ptr @void_func0, ptr @void_func1]
+; THRESHOLD-0: @func_array_addrspace_42 = addrspace(42) constant [2 x ptr addrspace(42)] [ptr addrspace(42) @func0_addrspace_42, ptr addrspace(42) @func1_addrspace_42]
+;.
 define i32 @func0() !guid !0 {
+; CHECK-LABEL: define i32 @func0(
+; CHECK-SAME: ) !guid [[META0:![0-9]+]] {
+; CHECK-NEXT:    ret i32 1
+;
+; THRESHOLD-0-LABEL: define i32 @func0(
+; THRESHOLD-0-SAME: ) !guid [[META0:![0-9]+]] {
+; THRESHOLD-0-NEXT:    ret i32 1
+;
   ret i32 1
 }
 
 define i32 @func1() !guid !1 {
+; CHECK-LABEL: define i32 @func1(
+; CHECK-SAME: ) !guid [[META1:![0-9]+]] {
+; CHECK-NEXT:    ret i32 2
+;
+; THRESHOLD-0-LABEL: define i32 @func1(
+; THRESHOLD-0-SAME: ) !guid [[META1:![0-9]+]] {
+; THRESHOLD-0-NEXT:    ret i32 2
+;
   ret i32 2
 }
 
@@ -20,7 +45,7 @@ define i32 @function_with_jump_table(i32 %index) {
 ; CHECK-NEXT:    switch i32 [[INDEX]], label [[DEFAULT_SWITCH_CASE_UNREACHABLE:%.*]] [
 ; CHECK-NEXT:      i32 0, label [[CALL_0:%.*]]
 ; CHECK-NEXT:      i32 1, label [[CALL_1:%.*]]
-; CHECK-NEXT:    ]
+; CHECK-NEXT:    ], !prof [[PROF2:![0-9]+]]
 ; CHECK:       default.switch.case.unreachable:
 ; CHECK-NEXT:    unreachable
 ; CHECK:       call.0:
@@ -37,7 +62,7 @@ define i32 @function_with_jump_table(i32 %index) {
 ; THRESHOLD-0-SAME: i32 [[INDEX:%.*]]) {
 ; THRESHOLD-0-NEXT:    [[GEP:%.*]] = getelementptr inbounds [2 x ptr], ptr @func_array, i32 0, i32 [[INDEX]]
 ; THRESHOLD-0-NEXT:    [[FUNC_PTR:%.*]] = load ptr, ptr [[GEP]], align 8
-; THRESHOLD-0-NEXT:    [[RESULT:%.*]] = call i32 [[FUNC_PTR]]()
+; THRESHOLD-0-NEXT:    [[RESULT:%.*]] = call i32 [[FUNC_PTR]](), !prof [[PROF2:![0-9]+]]
 ; THRESHOLD-0-NEXT:    ret i32 [[RESULT]]
 ;
   %gep = getelementptr inbounds [2 x ptr], ptr @func_array, i32 0, i32 %index
@@ -54,7 +79,7 @@ define i32 @basic_block_splitted_twice(i32 %index) {
 ; CHECK-NEXT:    switch i32 [[INDEX]], label [[DEFAULT_SWITCH_CASE_UNREACHABLE:%.*]] [
 ; CHECK-NEXT:      i32 0, label [[CALL_0:%.*]]
 ; CHECK-NEXT:      i32 1, label [[CALL_1:%.*]]
-; CHECK-NEXT:    ]
+; CHECK-NEXT:    ], !prof [[PROF3:![0-9]+]]
 ; CHECK:       default.switch.case.unreachable:
 ; CHECK-NEXT:    unreachable
 ; CHECK:       call.0:
@@ -70,7 +95,7 @@ define i32 @basic_block_splitted_twice(i32 %index) {
 ; CHECK-NEXT:    switch i32 [[INDEX]], label [[DEFAULT_SWITCH_CASE_UNREACHABLE1:%.*]] [
 ; CHECK-NEXT:      i32 0, label [[CALL_02:%.*]]
 ; CHECK-NEXT:      i32 1, label [[CALL_13:%.*]]
-; CHECK-NEXT:    ]
+; CHECK-NEXT:    ], !prof [[PROF3]]
 ; CHECK:       default.switch.case.unreachable1:
 ; CHECK-NEXT:    unreachable
 ; CHECK:       call.02:
@@ -106,10 +131,22 @@ define i32 @basic_block_splitted_twice(i32 %index) {
 }
 
 define void @void_func0() {
+; CHECK-LABEL: define void @void_func0() {
+; CHECK-NEXT:    ret void
+;
+; THRESHOLD-0-LABEL: define void @void_func0() {
+; THRESHOLD-0-NEXT:    ret void
+;
   ret void
 }
 
 define void @void_func1() {
+; CHECK-LABEL: define void @void_func1() {
+; CHECK-NEXT:    ret void
+;
+; THRESHOLD-0-LABEL: define void @void_func1() {
+; THRESHOLD-0-NEXT:    ret void
+;
   ret void
 }
 
@@ -123,7 +160,7 @@ define void @void_function_with_jump_table(i32 %index) {
 ; CHECK-NEXT:    switch i32 [[INDEX]], label [[DEFAULT_SWITCH_CASE_UNREACHABLE:%.*]] [
 ; CHECK-NEXT:      i32 0, label [[CALL_0:%.*]]
 ; CHECK-NEXT:      i32 1, label [[CALL_1:%.*]]
-; CHECK-NEXT:    ]
+; CHECK-NEXT:    ], !prof [[PROF3]]
 ; CHECK:       default.switch.case.unreachable:
 ; CHECK-NEXT:    unreachable
 ; CHECK:       call.0:
@@ -156,7 +193,7 @@ define void @void_function_with_jump_table_and_call_site_attr(i32 %index) {
 ; CHECK-NEXT:    switch i32 [[INDEX]], label [[DEFAULT_SWITCH_CASE_UNREACHABLE:%.*]] [
 ; CHECK-NEXT:      i32 0, label [[CALL_0:%.*]]
 ; CHECK-NEXT:      i32 1, label [[CALL_1:%.*]]
-; CHECK-NEXT:    ]
+; CHECK-NEXT:    ], !prof [[PROF3]]
 ; CHECK:       default.switch.case.unreachable:
 ; CHECK-NEXT:    unreachable
 ; CHECK:       call.0:
@@ -183,10 +220,22 @@ define void @void_function_with_jump_table_and_call_site_attr(i32 %index) {
 
 
 define i32 @func0_addrspace_42() addrspace(42) {
+; CHECK-LABEL: define i32 @func0_addrspace_42() addrspace(42) {
+; CHECK-NEXT:    ret i32 1
+;
+; THRESHOLD-0-LABEL: define i32 @func0_addrspace_42() addrspace(42) {
+; THRESHOLD-0-NEXT:    ret i32 1
+;
   ret i32 1
 }
 
 define i32 @func1_addrspace_42() addrspace(42) {
+; CHECK-LABEL: define i32 @func1_addrspace_42() addrspace(42) {
+; CHECK-NEXT:    ret i32 2
+;
+; THRESHOLD-0-LABEL: define i32 @func1_addrspace_42() addrspace(42) {
+; THRESHOLD-0-NEXT:    ret i32 2
+;
   ret i32 2
 }
 
@@ -200,7 +249,7 @@ define i32 @function_with_jump_table_addrspace_42(i32 %index) addrspace(42) {
 ; CHECK-NEXT:    switch i32 [[INDEX]], label [[DEFAULT_SWITCH_CASE_UNREACHABLE:%.*]] [
 ; CHECK-NEXT:      i32 0, label [[CALL_0:%.*]]
 ; CHECK-NEXT:      i32 1, label [[CALL_1:%.*]]
-; CHECK-NEXT:    ]
+; CHECK-NEXT:    ], !prof [[PROF3]]
 ; CHECK:       default.switch.case.unreachable:
 ; CHECK-NEXT:    unreachable
 ; CHECK:       call.0:
@@ -228,4 +277,18 @@ define i32 @function_with_jump_table_addrspace_42(i32 %index) addrspace(42) {
 
 !0 = !{i64 5678}
 !1 = !{i64 5555}
-!2 = !{!"VP", i32 0, i64 25, i64 5678, i64 20, i64 5555, i64 5}
\ No newline at end of file
+!2 = !{!"VP", i32 0, i64 25, i64 5678, i64 20, i64 5555, i64 5}
+;.
+; CHECK: attributes #[[ATTR0]] = { nounwind }
+;.
+; THRESHOLD-0: attributes #[[ATTR0]] = { nounwind }
+;.
+; CHECK: [[META0]] = !{i64 5678}
+; CHECK: [[META1]] = !{i64 5555}
+; CHECK: [[PROF2]] = !{!"branch_weights", i32 0, i32 20, i32 5}
+; CHECK: [[PROF3]] = !{!"unknown"}
+;.
+; THRESHOLD-0: [[META0]] = !{i64 5678}
+; THRESHOLD-0: [[META1]] = !{i64 5555}
+; THRESHOLD-0: [[PROF2]] = !{!"VP", i32 0, i64 25, i64 5678, i64 20, i64 5555, i64 5}
+;.

@mtrofin mtrofin force-pushed the users/mtrofin/08-14-_jts_use_common_branch_weigth_downscaling branch from 5c51af5 to dc4a59c Compare August 15, 2025 04:34
@mtrofin mtrofin force-pushed the users/mtrofin/08-14-_nfc_pgo_factor_downscaling_of_branch_weights_out_of_instrumentation_into_profiledata_ branch from 5b1cbec to 8c2429e Compare August 15, 2025 04:34
Copy link
Contributor

@boomanaiden154 boomanaiden154 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in the commit title (s/weigth/weight)?

@mtrofin mtrofin changed the title [JTS] Use common branch weigth downscaling [JTS] Use common branch weight downscaling Aug 15, 2025
Copy link
Member Author

mtrofin commented Aug 15, 2025

Merge activity

  • Aug 15, 5:17 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Aug 15, 6:08 AM UTC: Graphite rebased this pull request as part of a merge.
  • Aug 15, 6:17 AM UTC: Graphite rebased this pull request as part of a merge.
  • Aug 15, 6:26 AM UTC: Graphite rebased this pull request as part of a merge.
  • Aug 15, 6:47 AM UTC: Graphite rebased this pull request as part of a merge.
  • Aug 15, 6:59 AM UTC: Graphite rebased this pull request as part of a merge.
  • Aug 15, 7:02 AM UTC: Graphite rebased this pull request as part of a merge.
  • Aug 15, 7:05 AM UTC: Graphite rebased this pull request as part of a merge.
  • Aug 15, 7:33 AM UTC: Graphite couldn't merge this PR because it failed for an unknown reason.

@mtrofin mtrofin force-pushed the users/mtrofin/08-14-_nfc_pgo_factor_downscaling_of_branch_weights_out_of_instrumentation_into_profiledata_ branch 2 times, most recently from 859616d to 5ffa9b3 Compare August 15, 2025 05:32
Base automatically changed from users/mtrofin/08-14-_nfc_pgo_factor_downscaling_of_branch_weights_out_of_instrumentation_into_profiledata_ to main August 15, 2025 05:44
@mtrofin mtrofin force-pushed the users/mtrofin/08-14-_jts_use_common_branch_weigth_downscaling branch from dc4a59c to 43b197c Compare August 15, 2025 05:45
@mtrofin mtrofin enabled auto-merge (squash) August 15, 2025 06:05
@mtrofin mtrofin force-pushed the users/mtrofin/08-14-_jts_use_common_branch_weigth_downscaling branch 6 times, most recently from 0c45985 to cd7acac Compare August 15, 2025 07:02
@mtrofin mtrofin force-pushed the users/mtrofin/08-14-_jts_use_common_branch_weigth_downscaling branch from cd7acac to 91f8130 Compare August 15, 2025 07:05
@mtrofin mtrofin merged commit b8d74ad into main Aug 15, 2025
9 checks passed
@mtrofin mtrofin deleted the users/mtrofin/08-14-_jts_use_common_branch_weigth_downscaling branch August 15, 2025 07:30
@llvm-ci
Copy link
Collaborator

llvm-ci commented Aug 15, 2025

LLVM Buildbot has detected a new failure on builder clangd-ubuntu-tsan running on clangd-ubuntu-clang while building llvm at step 2 "checkout".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/134/builds/24454

Here is the relevant piece of the build log for the reference
Step 2 (checkout) failure: update (failure)
git version 2.17.1
fatal: unable to access 'https://github.com/llvm/llvm-project.git/': Could not resolve host: github.com
fatal: unable to access 'https://github.com/llvm/llvm-project.git/': Could not resolve host: github.com

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants